﻿namespace KinonekoSoftware.Studio.Utils
{
    public delegate ModulePresenter ModuleBlockFactory(ModuleBase target, IModuleMessageBus bus);

    public partial class ModuleFactory
    {
        private readonly Dictionary<Type, ModuleBlockFactory> _Handler;
        private readonly IModuleMessageBus                    _MessageBus;

        public ModuleFactory(IModuleMessageBus bus)
        {
            _Handler    = new Dictionary<Type, ModuleBlockFactory>();
            _MessageBus = bus ?? throw new ArgumentNullException(nameof(bus));

            Initialize();
        }


        private void Initialize()
        {
            _Handler.TryAdd(typeof(Block_RVE), Handle_Block_RVE);
            _Handler.TryAdd(typeof(Block_Switch), Handle_Block_Switch);
            _Handler.TryAdd(typeof(Block_Text), Handle_Block_Text);
            _Handler.TryAdd(typeof(Block_LeadingText), Handle_Block_LeadingText);
            _Handler.TryAdd(typeof(Block_Numeric), Handle_Block_Numeric);
            _Handler.TryAdd(typeof(Block_Paragraph), Handle_Block_Paragraph);
            _Handler.TryAdd(typeof(Block_Color), Handle_Block_Color);
            _Handler.TryAdd(typeof(Block_Degree), Handle_Block_Degree);
        }

        //
        // TODO: step 5：创建ModuleBlockFactory方法

        private ModulePresenter Handle_Block_Degree(ModuleBase block, IModuleMessageBus bus)
        {
            var rve = (Block_Degree)block;
            return new DegreeGroupPresenter(rve, bus);
        }

        private ModulePresenter Handle_Block_RVE(ModuleBase block, IModuleMessageBus bus)
        {
            var rve = (Block_RVE)block;
            return new RVEGroupPresenter(rve, bus);
        }

        private static ModulePresenter Handle_Block_Switch(ModuleBase block, IModuleMessageBus bus)
        {
            var target = (Block_Switch)block;
            return new SwitchGroupPresenter(target, bus);
        }

        private static ModulePresenter Handle_Block_Numeric(ModuleBase block, IModuleMessageBus bus)
        {
            var target = (Block_Numeric)block;

            if (target.Style == NumericStyle.Degree)
            {
                return new DegreeNumericGroupPresenter(target, bus);
            }

            if (target.Style == NumericStyle.Progress)
            {
                return new ProgressNumericGroupPresenter(target, bus);
            }

            return new ChartNumericGroupPresenter(target, bus);
        }

        private static ModulePresenter Handle_Block_Paragraph(ModuleBase block, IModuleMessageBus bus)
        {
            var target = (Block_Paragraph)block;
            return new ParagraphBlockPresenter(target, bus);
        }

        private static ModulePresenter Handle_Block_LeadingText(ModuleBase block, IModuleMessageBus bus)
        {
            var target = (Block_LeadingText)block;
            return new LeadingTextBlockPresenter(target, bus);
        }

        private static ModulePresenter Handle_Block_Text(ModuleBase block, IModuleMessageBus bus)
        {
            var target = (Block_Text)block;
            return new TextGroupPresenter(target, bus);
        }

        private static ModulePresenter Handle_Block_Color(ModuleBase block, IModuleMessageBus bus)
        {
            var target = (Block_Color)block;
            return new ColorGroupPresenter(target, bus);
        }

        public ModulePresenter Get(ModuleBase element)
        {
            if (_Handler.TryGetValue(element.GetType(), out var handler))
            {
                return handler(element, _MessageBus);
            }

            return null;
        }
    }

    partial class ModuleFactory
    {
        //
        // TODO: step 6， 添加ModulePresenter第二步，创建By ModuleBlockType 方法
        public static ModuleBlock CreateBlock(ModuleBlockType type)
        {
            return type switch
            {
                ModuleBlockType.Color       => Block_Color.CreateInstance(),
                ModuleBlockType.Numeric     => Block_Numeric.CreateInstance(NumericStyle.Progress),
                ModuleBlockType.Paragraph   => Block_Paragraph.CreateInstance(),
                ModuleBlockType.Text        => Block_Text.CreateInstance(),
                ModuleBlockType.Switch      => Block_Switch.CreateInstance(),
                ModuleBlockType.LeadingText => Block_LeadingText.CreateInstance(),
                ModuleBlockType.Degree      => Block_Degree.CreateInstance(),

                _ => Block_RVE.CreateInstance(),
            };
        }
    }
}